package cn.woblog.android.downloader.observable;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Observable;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import cn.woblog.android.downloader.domain.DownloadInfo;
import cn.woblog.android.downloader.domain.DownloadStatus;
import cn.woblog.android.downloader.thread.DownloadTask;
import cn.woblog.android.downloader.utils.MyLog;

public class DataChanger extends Observable {

	private static DataChanger instance;
	private Context context;
	private Map<String, DownloadInfo> downloads;
	private Map<String, DownloadInfo> notifiyDatas;
	private Map<String, DownloadInfo> notifiyTemps;
	private Map<String, DownloadTask> downloadTasks;
	private Map<String, DownloadTask> pauseTasks;
	private Timer timer;
	private TimerTask timerTask;
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 0:
				notififyData();
				break;
			case 1:
				notififyOneData((DownloadInfo) msg.obj);
				break;
			case 2:
				notififyDeleteData((DownloadInfo) msg.obj);
				break;

			default:
				break;
			}
		};
	};
	private DownloadInfo value;
	private boolean isNotify;

	public DataChanger(Context context) {
		this.context = context;
		downloads = new LinkedHashMap<String, DownloadInfo>();
		notifiyDatas = new LinkedHashMap<String, DownloadInfo>();
		notifiyTemps = new LinkedHashMap<String, DownloadInfo>();
		downloadTasks = new LinkedHashMap<String, DownloadTask>();
		pauseTasks = new LinkedHashMap<String, DownloadTask>();
	}

	protected void notififyDeleteData(DownloadInfo info) {
		setChanged();
		notifyObservers(info);
	}

	protected void notififyOneData(DownloadInfo info) {
		setChanged();
		notifyObservers(info);
	}

	protected synchronized void notififyData() {
		isNotify = true;
		if (notifiyDatas.size() > 0) {
			for (Map.Entry<String, DownloadInfo> item : notifiyDatas.entrySet()) {
				value = item.getValue();
				if (value != null) {
					setChanged();
					notifyObservers(value);
				}
			}
		}
		isNotify = false;
	}

	public static DataChanger getInstance(Context context) {
		if (instance == null) {
			instance = new DataChanger(context);
		}
		return instance;
	}

	public int getDownloadSize() {
		return downloads.size();
	}

	public int getDownloadTaskSize() {
		return downloadTasks.size();
	}

	public DownloadInfo getNextDownloadInfo() {
		if (downloads.size() > 0) {
			DownloadInfo value2;
			for (Map.Entry<String, DownloadInfo> item : downloads.entrySet()) {
				value2 = item.getValue();
				if (value2 != null
						&& value2.getStatus() == DownloadStatus.WAITING) {
					return value2;
				}
			}
		}
		return null;
	}

	public DownloadTask getDownloadTask(String id) {
		return downloadTasks.get(id);
	}

	public Map<String, DownloadTask> getDownloadTasks() {
		return downloadTasks;
	}

	public void removeDownloadTask(String id) {
		downloadTasks.remove(id);
	}

	public void addDownload(String id, DownloadInfo info) {
		downloads.put(id, info);
	}

	public void removeDownload(String id) {
		downloads.remove(id);
	}

	public void addTask(String id, DownloadTask task) {
		downloadTasks.put(id, task);
	}

	public synchronized void addNotifiy(DownloadInfo info) {
		if (!isNotify) {
			notifiyDatas.put(info.getId(), info);
			if (notifiyTemps.size() > 0) {
				notifiyDatas.putAll(notifiyTemps);
				notifiyTemps.clear();
			}
		} else {
			notifiyTemps.put(info.getId(), info);
		}
	}

	public void removeNotifiy(String id) {
		notifiyDatas.remove(id);
	}

	public void startNotifyLooper() {
		if (timer == null || timerTask == null) {
			MyLog.d("start notifiy looper");
			timer = new Timer();
			timerTask = new TimerTask() {

				@Override
				public void run() {
					handler.sendEmptyMessage(0);
					stopNotifyLooper();
				}
			};
			timer.schedule(timerTask, 0, 1000);
		}
	}

	public void stopNotifyLooper() {
		if (downloadTasks.size() <= 0) {
			MyLog.d("stop notifiy looper");
			if (timer != null) {
				timer.cancel();
				timer = null;
			}
			if (timerTask != null) {
				timerTask.cancel();
				timerTask = null;
			}
		}
	}

	public void notifyOne(DownloadInfo info) {
		Message message = handler.obtainMessage(1, info);
		handler.sendMessage(message);
	}

	public void addPauseTask(String id, DownloadTask task) {
		pauseTasks.put(id, task);
	}

	public void removePauseTask(String id) {
		pauseTasks.remove(id);
	}

	public DownloadTask getPauseTask(String id) {
		return pauseTasks.get(id);
	}

	public DownloadInfo getDownload(String id) {
		return downloads.get(id);
	}

	public void notifyDeleteDataById(String id) {
		DownloadInfo info = downloads.get(id);
		if (info != null) {
			info.setStatus(DownloadStatus.DELETE);
			Message message = handler.obtainMessage(2, info);
			handler.sendMessage(message);
		}
	}
}
